package algorithm;

import io.OutputWriter;
import io.SxpcFileReader;
import java.io.IOException;
import java.util.Vector;
import datastructures.MapfileWrapper;
import pac.SearchDatastructure;

public class TestCombinations {

	private SearchDatastructure searcher;
	private OutputWriter outputter;
	private MapfileWrapper snpSet;
	private Vector<String[]> variables;
	
	public TestCombinations(SearchDatastructure I, OutputWriter O) throws IOException 
	{
		searcher = I;
		outputter = O;
		snpSet = new MapfileWrapper(searcher.snpList);
	}

	
	/*
	 * process hitsfile
	 */
	private void readHitsFile ( String hitsFileName ) 
	{
		try
		{
			SxpcFileReader s = new SxpcFileReader();
			variables = s.readUnprocessedHitsFile(hitsFileName);
			if(variables == null) {
				System.out.println("Nothing to process.");
				System.exit(1);
			}			
		} catch (IOException e) {			
				e.printStackTrace();
				System.exit(1);
		}
	}
	
	private int[][] getVariablesAroundSpan ( int[] pivotVariables ) 
	{		
		int totalVariables = searcher.userParams.getSpan() + 1 + searcher.userParams.getSpan();
		
		int[] Xaxis = new int[totalVariables];
		int[] Yaxis = new int[totalVariables];
		
		for(int i=searcher.userParams.getSpan(); i>0; i--) {
			Xaxis[searcher.userParams.getSpan()-i] = pivotVariables[0] - 2*i; //i;
			Yaxis[searcher.userParams.getSpan()-i] = pivotVariables[1]- 2*i; //i;
		}
		
		Xaxis[searcher.userParams.getSpan()] = pivotVariables[0];
		Yaxis[searcher.userParams.getSpan()] = pivotVariables[1];
		
		for(int i=1; i<=searcher.userParams.getSpan(); i++) {
			Xaxis[searcher.userParams.getSpan()+i] = pivotVariables[0]+ 2*i; //i;
			Yaxis[searcher.userParams.getSpan()+i] = pivotVariables[1]+ 2*i; //i;
		}
		
		int[][] variableArray = new int[totalVariables*totalVariables][2];
		for(int i=0; i<Xaxis.length; i++) {
			for(int j=0; j<Yaxis.length; j++) {
				variableArray[i*totalVariables+j][0] = Xaxis[i];
				variableArray[i*totalVariables+j][1] = Yaxis[j];
			}
		}
		
		return variableArray;
	}
	
	
	
	private String[][] getRowAndColLabels ( int[] pivotVariables ) 
	{
		String[][] rowAndColLabels = new String[2][2*searcher.userParams.getSpan()+1];
		
		for(int row_var = -2*searcher.userParams.getSpan(); row_var <= 2*searcher.userParams.getSpan() ; row_var+=2) 
		{
			int currentVariable = pivotVariables[0] + row_var;
			int row = (2*searcher.userParams.getSpan() + row_var)/2;
			String mode = (currentVariable%2 == 0) ? "d" : "r";
			rowAndColLabels[0][row] = snpSet.getSNPInfo( (int) Math.floor(currentVariable/2) ).getRsid()+","+mode;
		}
		for(int col_var = -2*searcher.userParams.getSpan(); col_var <= 2*searcher.userParams.getSpan() ; col_var+=2)
		{
			int currentVariable = pivotVariables[1] + col_var;
			int col = (2*searcher.userParams.getSpan() + col_var)/2;
			String mode = (currentVariable%2 == 0) ? "d" : "r";
			rowAndColLabels[1][col] = snpSet.getSNPInfo( (int) Math.floor(currentVariable/2) ).getRsid()+","+mode;
		}
		
		return rowAndColLabels;
	}
	
	
	
	public void getSignificance ( String hitsFileName ) throws IOException 
	{
		readHitsFile(hitsFileName);
		int[][] variableArray = new int[variables.size()][2];

		//default: list of entries
		double[][] pvalMatrix = new double[variables.size()][1];
		
		if(searcher.userParams.getSpan()==0) {
			for(int hit=0; hit<variables.size(); hit++) 
				variableArray[hit] = snpSet.interactionToVariables(variables.elementAt(hit));
		}
		else {
			int[] pivotVariables = snpSet.interactionToVariables(variables.elementAt(0));
			variableArray = getVariablesAroundSpan(pivotVariables);
			pvalMatrix = new double[2*searcher.userParams.getSpan()+1][2*searcher.userParams.getSpan()+1];
		}
		
		
		for(int len=0; len<variableArray.length; len++) {
			int order = variableArray[len].length;	
			
			//2.5 : establish expected and observed on number of case carriers
			int[][] noOfCaseCarriers = searcher.snpIndices.getObservedCaseCarriers(searcher.userParams, variableArray[len]);
			double pvalueCaseOnly = searcher.significance.TestCasesOnly ( order,noOfCaseCarriers );

			int[][] noOfControlCarriers = searcher.snpIndices.getObservedControlCarriers(searcher.userParams, variableArray[len]);
			double pvalueCaseControl = searcher.significance.TestCasesVsControls ( order, noOfCaseCarriers, noOfControlCarriers );

			if ( 	(variableArray[len][0] == variableArray[len][1]) 
					|| (variableArray[len][0]-variableArray[len][1] == 1 && variableArray[len][0]%2==1 && variableArray[len][1]%2==0)
					|| (variableArray[len][1]-variableArray[len][0] == 1 && variableArray[len][1]%2==1 && variableArray[len][0]%2==0) 
				)
				pvalueCaseControl = 1;
			
			//depending on whether you are asked for a region, or for a list of specific entries, output accordingly.
			if ( searcher.userParams.getSpan() == 0 )
				outputter.WriteOutput ( variableArray[len], noOfCaseCarriers, pvalueCaseOnly, noOfControlCarriers, pvalueCaseControl );
			else 
				pvalMatrix[ (int) Math.floor((double) len / (2*searcher.userParams.getSpan()+1) ) ][len % (2*searcher.userParams.getSpan()+1) ] = pvalueCaseControl;
			
		}
	
		if(searcher.userParams.getSpan() != 0) {
			int[] pivotVariables = snpSet.interactionToVariables(variables.elementAt(0));
			String[][] rowAndColLabels = getRowAndColLabels(pivotVariables);
			outputter.writeOutputMatrix(pvalMatrix, rowAndColLabels);
		}
		System.out.println("Finished.");
		outputter.Close();
	
	}
	
	
}
